<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Highscore - The Boost C++ Libraries - Multithreading</title>
<link rel="stylesheet" href="css/highscore.css" type="text/css">
<link rev="made" href="mailto:boris@highscore.de">
<link rel="home" href="frontpage.html" title="The Boost C++ Libraries">
<link rel="up" href="frontpage.html" title="The Boost C++ Libraries">
<link rel="prev" href="stringhandling.html" title="Chapter 5: String Handling">
<link rel="next" href="asio.html" title="Chapter 7: Asynchronous Input and Output">
<link rel="chapter" href="introduction.html" title="Chapter 1: Introduction">
<link rel="chapter" href="smartpointers.html" title="Chapter 2: Smart Pointers">
<link rel="chapter" href="functionobjects.html" title="Chapter 3: Function Objects">
<link rel="chapter" href="eventhandling.html" title="Chapter 4: Event Handling">
<link rel="chapter" href="stringhandling.html" title="Chapter 5: String Handling">
<link rel="chapter" href="multithreading.html" title="Chapter 6: Multithreading">
<link rel="chapter" href="asio.html" title="Chapter 7: Asynchronous Input and Output">
<link rel="chapter" href="interprocesscommunication.html" title="Chapter 8: Interprocess Communication">
<link rel="chapter" href="filesystem.html" title="Chapter 9: Filesystem">
<link rel="chapter" href="datetime.html" title="Chapter 10: Date and Time">
<link rel="chapter" href="serialization.html" title="Chapter 11: Serialization">
<link rel="chapter" href="parser.html" title="Chapter 12: Parser">
<link rel="chapter" href="containers.html" title="Chapter 13: Containers">
<link rel="chapter" href="datastructures.html" title="Chapter 14: Data Structures">
<link rel="chapter" href="errorhandling.html" title="Chapter 15: Error Handling">
<link rel="chapter" href="castoperators.html" title="Chapter 16: Cast Operators">
<link rel="section" href="multithreading.html#multithreading_general" title="6.1 General">
<link rel="section" href="multithreading.html#multithreading_thread_management" title="6.2 Thread Management">
<link rel="section" href="multithreading.html#multithreading_synchronization" title="6.3 Synchronization">
<link rel="section" href="multithreading.html#multithreading_thread_local_storage" title="6.4 Thread Local Storage">
<link rel="section" href="multithreading.html#multithreading_exercises" title="6.5 Exercises">
<meta http-equiv="pics-label" content='(pics-1.1 "http://www.icra.org/ratingsv02.html" l gen true for "http://www.highscore.de" r (nz 1 vz 1 lz 1 oz 1 cz 1) gen true for "http://highscore.de" r (nz 1 vz 1 lz 1 oz 1 cz 1))'>
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<link href="http://www.highscore.de/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon">
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script><script type="text/javascript" src="js/jquery.event.drag-1.5.min.js"></script><script type="text/javascript" src="js/highscore.js"></script>
</head>
<body>
<div lang="en" class="docbook chapter" title="Chapter 6: Multithreading">
<p class="title">The Boost C++ Libraries</p>
<script type="text/javascript">
          var titlepage = "Front page";
        
      var titles = new Array(titlepage,
      
        "Chapter 1: Introduction",
      
        "Chapter 2: Smart Pointers",
      
        "Chapter 3: Function Objects",
      
        "Chapter 4: Event Handling",
      
        "Chapter 5: String Handling",
      
        "Chapter 6: Multithreading",
      
        "Chapter 7: Asynchronous Input and Output",
      
        "Chapter 8: Interprocess Communication",
      
        "Chapter 9: Filesystem",
      
        "Chapter 10: Date and Time",
      
        "Chapter 11: Serialization",
      
        "Chapter 12: Parser",
      
        "Chapter 13: Containers",
      
        "Chapter 14: Data Structures",
      
        "Chapter 15: Error Handling",
      
        "Chapter 16: Cast Operators",
      
      "");

      
          var titlehtml = "frontpage.html";
        
      var filenames = new Array(titlehtml,
      
        "introduction.html",
      
        "smartpointers.html",
      
        "functionobjects.html",
      
        "eventhandling.html",
      
        "stringhandling.html",
      
        "multithreading.html",
      
        "asio.html",
      
        "interprocesscommunication.html",
      
        "filesystem.html",
      
        "datetime.html",
      
        "serialization.html",
      
        "parser.html",
      
        "containers.html",
      
        "datastructures.html",
      
        "errorhandling.html",
      
        "castoperators.html",
      
      "");

      
      document.open();
      document.write('<form action="" class="toc">');
      document.write('<select size="1" onchange="location.href=options[selectedIndex].value">');
      for (var i = 0; i < titles.length && i < filenames.length; ++i) {
        if (titles[i] != "" && filenames[i] != "") {
          document.write('<option');
          document.write(' value="' + filenames[i] + '"');
          var expr = new RegExp('[/\]' + filenames[i] + '$');
          if (expr.test(location.href)) {
            document.write(' selected="selected"');
          }
          document.write('>' + titles[i] + '<\/option>');
        }
      }
      document.write('<\/select>');
      document.write('<\/form>');
      document.close();
      
    </script><noscript><p class="toc"><a href="toc.html">Table of Contents</a></p></noscript>
<hr class="hrhead">
<h1 class="title">
<a name="multithreading"></a><small>Chapter 6:</small> Multithreading</h1>
<hr>
<div class="toc">
<h3>Table of Contents</h3>
<ul>
<li><span class="sect1"><a href="multithreading.html#multithreading_general">6.1 General</a></span></li>
<li><span class="sect1"><a href="multithreading.html#multithreading_thread_management">6.2 Thread Management</a></span></li>
<li><span class="sect1"><a href="multithreading.html#multithreading_synchronization">6.3 Synchronization</a></span></li>
<li><span class="sect1"><a href="multithreading.html#multithreading_thread_local_storage">6.4 Thread Local Storage</a></span></li>
<li><span class="sect1"><a href="multithreading.html#multithreading_exercises">6.5 Exercises</a></span></li>
</ul>
</div>
<p class="license"><a href="http://creativecommons.org/licenses/by-nc-nd/3.0/" rel="license" target="_top"><img src="img/88x31_cc_logo.gif" alt="" width="88" height="31"></a> This book is licensed under a <a href="http://creativecommons.org/licenses/by-nc-nd/3.0/" rel="license" target="_top">Creative Commons License</a>.</p>
<hr>
<h2 class="title">
<a name="multithreading_general"></a>6.1 General</h2>
<div class="sect1">
<p>Threads are discrete processing sequences that allow execution of different functions within a given application at the same time. This becomes important if a function, known to take a long time for a specific calculation, should not block a different function while executing. Threads actually allow the simultaneous execution of two functions without having one waiting for the other.</p>
<p>Once an application is launched, it contains only one thread by default. This thread executes the <code class="function">main()</code> function. Functions called from within <code class="function">main()</code> are executed sequentially in the context of this thread. Such a program is called a single threaded application.</p>
<p>In contrast, programs that create new threads are called multithreaded applications. Not only can they execute multiple functions at the same time, they also become more and more important these days since computers now ship with CPUs containing more than one core by default. Since multiple cores allow the execution of different functions simultaneously, they put a burden on the developer to use the available processing capacity accordingly. While threads have always been used whenever different functions should execute concurrently, developers now are more and more forced to carefully structure their applications to support this concurrency. Knowledge of multithreaded programming thus becomes more and more important in the age of multi-core systems.</p>
<p>This chapter introduces the Boost C++ Library <a class="link" href="http://www.boost.org/libs/thread/">Boost.Thread</a> that allows the development of platform independent multithreaded applications.</p>
</div>
<hr>
<h2 class="title">
<a name="multithreading_thread_management"></a>6.2 Thread Management</h2>
<div class="sect1">
<p>The most important class in this library is <code class="classname">boost::thread</code>, defined in <code class="filename">boost/thread.hpp</code>, which is used to create a new thread. The following example shows how to apply it.</p>
<pre class="programlisting">#include &lt;boost/thread.hpp&gt; 
#include &lt;iostream&gt; 

void wait(int seconds) 
{ 
  boost::this_thread::sleep(boost::posix_time::seconds(seconds)); 
} 

void thread() 
{ 
  for (int i = 0; i &lt; 5; ++i) 
  { 
    wait(1); 
    std::cout &lt;&lt; i &lt;&lt; std::endl; 
  } 
} 

int main() 
{ 
  boost::thread t(thread); 
  t.join(); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/6.2.1/main.cpp">Download source code</a></li></ul>
<p>The name of the function that should execute within the thread is passed to the constructor of <code class="classname">boost::thread</code>. Once the variable <var>t</var> in the above example is created, the <code class="function">thread()</code> function starts executing in its own thread immediately. At this point, <code class="function">thread()</code> executes concurrently with the <code class="function">main()</code> function.</p>
<p>To keep the application from terminating, the <code class="methodname">join()</code> method is called on the newly created thread. <code class="methodname">join()</code> is a blocking call: It blocks the current thread until the thread, for which <code class="methodname">join()</code> was called, has terminated. This causes <code class="function">main()</code> to wait until <code class="function">thread()</code> has terminated.</p>
<p>As seen in the above example, a particular thread can be accessed via a variable such as <var>t</var> in order to e.g. wait for its termination using the <code class="methodname">join()</code> method. However, the thread will continue to execute even if <var>t</var> loses its scope and is destroyed. A thread always binds to a variable of type <code class="classname">boost::thread</code> in the beginning, but once created, depends no longer on it. There even exists a method called <code class="methodname">detach()</code> that allows to decouple a variable of type <code class="classname">boost::thread</code> from its corresponding thread. Certainly, methods such as <code class="methodname">join()</code> cannot be called afterwards since the variable does not represent a valid thread any longer.</p>
<p>Anything that can be done inside a function can also be done inside a thread. Ultimately, a thread is no different than a function - except that it is executed concurrently. In the example above, five numbers are written to the standard output stream using a loop. To slow down the output, every iteration of the loop calls the <code class="function">wait()</code> function to stall execution for one second. <code class="function">wait()</code> employs a function named <code class="function">sleep()</code> that also originates from Boost.Thread and resides in the <code class="code">boost::this_thread</code> namespace.</p>
<p><code class="function">sleep()</code> either expects a period of time or a specific point in time indicating how long or until when the current thread should be stalled. By passing an object of type <code class="classname">boost::posix_time::seconds</code>, a period of time is specified in this example. <code class="classname">boost::posix_time::seconds</code> comes from the Boost.DateTime library that is used by Boost.Thread to manage and process time data.</p>
<p>While the previous example shows how to wait for a different thread, the following example rather shows how a thread can be interrupted by the means of so-called interruption points.</p>
<pre class="programlisting">#include &lt;boost/thread.hpp&gt; 
#include &lt;iostream&gt; 

void wait(int seconds) 
{ 
  boost::this_thread::sleep(boost::posix_time::seconds(seconds)); 
} 

void thread() 
{ 
  try 
  { 
    for (int i = 0; i &lt; 5; ++i) 
    { 
      wait(1); 
      std::cout &lt;&lt; i &lt;&lt; std::endl; 
    } 
  } 
  catch (boost::thread_interrupted&amp;) 
  { 
  } 
} 

int main() 
{ 
  boost::thread t(thread); 
  wait(3); 
  t.interrupt(); 
  t.join(); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/6.2.2/main.cpp">Download source code</a></li></ul>
<p>Calling <code class="methodname">interrupt()</code> on a thread object interrupts the corresponding thread. In this context, interrupted means that an exception of type <code class="classname">boost::thread_interrupted</code> is thrown inside the thread. However, this only happens once the thread reaches an interruption point.</p>
<p>Simply calling <code class="methodname">interrupt()</code> does not cause anything if the given thread does not contain any interruption points. Whenever a thread reaches an interruption point it will check whether the <code class="methodname">interrupt()</code> method has been called. Only if it has, a <code class="classname">boost::thread_interrupted</code> exception is thrown accordingly.</p>
<p>Boost.Thread defines a series of interruption points such as the <code class="function">sleep()</code> function. Since <code class="function">sleep()</code> is called five times in the example, the thread checks five times whether or not it was interrupted. Between the calls to <code class="function">sleep()</code>, the thread can not be interrupted though.</p>
<p>Once the program is executed, it will only print three numbers to the standard output stream. This is caused by calling the <code class="methodname">interrupt()</code> method after three seconds inside <code class="methodname">main()</code>. Thus, the corresponding thread is interrupted and throws a <code class="classname">boost::thread_interrupted</code> exception accordingly. While the exception is correctly caught inside the thread, the <code class="code">catch</code> handler is empty though. Since the <code class="function">thread()</code> function returns after the handler, the thread is terminated as well. This in turn will also terminate the entire application since <code class="function">main()</code> simply waited for the thread to terminate using the <code class="methodname">join()</code> method.</p>
<p>Boost.Thread defines about ten interruption points including the mentioned <code class="function">sleep()</code> function. Thanks to these interruption points, threads can easily be interrupted in a timely manner. However, they may not always be the best choice since an interruption point must be reached first in order to check for the <code class="classname">boost::thread_interrupted</code> exception.</p>
<p>To provide a rough overview over the different functions provided by Boost.Thread, the following example introduces two more.</p>
<pre class="programlisting">#include &lt;boost/thread.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  std::cout &lt;&lt; boost::this_thread::get_id() &lt;&lt; std::endl; 
  std::cout &lt;&lt; boost::thread::hardware_concurrency() &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/6.2.3/main.cpp">Download source code</a></li></ul>
<p>Using the namespace <code class="code">boost::this_thread</code>, independent functions are provided that apply to the current thread such as the <code class="function">sleep()</code> function shown before. Another one is <code class="function">get_id()</code>: It will return a number identifying the current thread. It is also provided as a method for <code class="classname">boost::thread</code>.</p>
<p>The static <code class="methodname">hardware_concurrency()</code> method, provided by the <code class="classname">boost::thread</code> class, returns the number of threads that could physically be executed at the same time based on the underlying number of CPUs or CPU cores. Calling this function on a commonly used dual-core machine, a value of 2 is returned. This allows for a simple method to identify the theoretical maximum number of threads that should be used simultaneously by a given multithreaded application.</p>
</div>
<hr>
<h2 class="title">
<a name="multithreading_synchronization"></a>6.3 Synchronization</h2>
<div class="sect1">
<p>While the usage of multiple threads can increase the performance of an application it usually also increases its complexity. If several functions execute at the same time using threads, access to shared resources must be synchronized accordingly. This involves quite some work once the application reaches a certain size. This paragraph introduces the classes provided by Boost.Thread for synchronizing threads.</p>
<pre class="programlisting">#include &lt;boost/thread.hpp&gt; 
#include &lt;iostream&gt; 

void wait(int seconds) 
{ 
  boost::this_thread::sleep(boost::posix_time::seconds(seconds)); 
} 

boost::mutex mutex; 

void thread() 
{ 
  for (int i = 0; i &lt; 5; ++i) 
  { 
    wait(1); 
    mutex.lock(); 
    std::cout &lt;&lt; "Thread " &lt;&lt; boost::this_thread::get_id() &lt;&lt; ": " &lt;&lt; i &lt;&lt; std::endl; 
    mutex.unlock(); 
  } 
} 

int main() 
{ 
  boost::thread t1(thread); 
  boost::thread t2(thread); 
  t1.join(); 
  t2.join(); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/6.3.1/main.cpp">Download source code</a></li></ul>
<p>Multithreaded programs use so-called mutex objects for synchronization. Boost.Thread provides different mutex classes, <code class="classname">boost::mutex</code> being the most simple one. The basic principle of a mutex is to prevent other threads from taking ownership while a particular thread owns it. Once released, a different thread can take ownership. This causes threads to wait until a different thread has finished processing some operations and thus releases its ownership of the mutex object accordingly. </p>
<p>The above example uses a global mutex object of type <code class="classname">boost::mutex</code> named <var>mutex</var>. The <code class="function">thread()</code> function takes ownership of this object right before it writes to the standard output stream inside the <code class="code">for</code> loop using the <code class="methodname">lock()</code> method. Once a message has been written, the ownership is released using the <code class="methodname">unlock()</code> method.</p>
<p><code class="function">main()</code> creates two threads, both executing the <code class="function">thread()</code> function. Using the <code class="code">for</code> loop, every thread counts to five, writing a message to the standard output stream with each iteration. Unfortunately, the standard output stream is a global object which is shared among all threads. The standard does not provide any guarantee that <var>std::cout</var> can be safely accessed from multiple threads. Thus, access to the standard output stream must be synchronized: At any given time, only one thread is allowed to access <var>std::cout</var>.</p>
<p>Since both threads try to acquire the mutex before writing to the standard output stream, it is guaranteed that only one thread at a time actually accesses <var>std::cout</var>. Disregarding which thread successfully calls the <code class="methodname">lock()</code> method, all other threads need to wait until <code class="methodname">unlock()</code> has been called.</p>
<p>Acquiring and releasing mutexes is a typical scheme and is supported by Boost.Thread through different data types. For example, instead of calling <code class="methodname">lock()</code> and <code class="methodname">unlock()</code> directly, the <code class="classname">boost::lock_guard</code> class can be used.</p>
<pre class="programlisting">#include &lt;boost/thread.hpp&gt; 
#include &lt;iostream&gt; 

void wait(int seconds) 
{ 
  boost::this_thread::sleep(boost::posix_time::seconds(seconds)); 
} 

boost::mutex mutex; 

void thread() 
{ 
  for (int i = 0; i &lt; 5; ++i) 
  { 
    wait(1); 
    boost::lock_guard&lt;boost::mutex&gt; lock(mutex); 
    std::cout &lt;&lt; "Thread " &lt;&lt; boost::this_thread::get_id() &lt;&lt; ": " &lt;&lt; i &lt;&lt; std::endl; 
  } 
} 

int main() 
{ 
  boost::thread t1(thread); 
  boost::thread t2(thread); 
  t1.join(); 
  t2.join(); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/6.3.2/main.cpp">Download source code</a></li></ul>
<p><code class="classname">boost::lock_guard</code> automatically calls <code class="methodname">lock()</code> and <code class="methodname">unlock()</code> inside its constructor and destructor, respectively. Access to the shared resource is as synchronized as it was when calling both methods explicitly. The <code class="classname">boost::lock_guard</code> class is yet another example of the RAII idiom presented in <a class="xref" href="smartpointers.html" title="Chapter 2: Smart Pointers">Chapter 2, <i>Smart Pointers</i></a>.</p>
<p>Besides <code class="classname">boost::mutex</code> and <code class="classname">boost::lock_guard</code>, Boost.Thread provides additional classes to support variations of synchronization. One of the essential ones is <code class="classname">boost::unique_lock</code> which, compared to <code class="classname">boost::lock_guard</code>, provides a number of helpful methods.</p>
<pre class="programlisting">#include &lt;boost/thread.hpp&gt; 
#include &lt;iostream&gt; 

void wait(int seconds) 
{ 
  boost::this_thread::sleep(boost::posix_time::seconds(seconds)); 
} 

boost::timed_mutex mutex; 

void thread() 
{ 
  for (int i = 0; i &lt; 5; ++i) 
  { 
    wait(1); 
    boost::unique_lock&lt;boost::timed_mutex&gt; lock(mutex, boost::try_to_lock); 
    if (!lock.owns_lock()) 
      lock.timed_lock(boost::get_system_time() + boost::posix_time::seconds(1)); 
    std::cout &lt;&lt; "Thread " &lt;&lt; boost::this_thread::get_id() &lt;&lt; ": " &lt;&lt; i &lt;&lt; std::endl; 
    boost::timed_mutex *m = lock.release(); 
    m-&gt;unlock(); 
  } 
} 

int main() 
{ 
  boost::thread t1(thread); 
  boost::thread t2(thread); 
  t1.join(); 
  t2.join(); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/6.3.3/main.cpp">Download source code</a></li></ul>
<p>The above example uses various methods to illustrate some of the features provided by <code class="classname">boost::unique_lock</code>. Certainly, the usage of these features does not necessarily make sense for the given scenario; the usage of <code class="classname">boost::lock_guard</code> in the previous example was already adequate. This example is rather meant to demonstrate the possibilities offered by <code class="classname">boost::unique_lock</code>.</p>
<p><code class="classname">boost::unique_lock</code> offers different ways of acquiring a mutex by providing multiple constructors. The one expecting only a mutex object simply calls the <code class="methodname">lock()</code> method and waits until the mutex has been acquired. It thus acts exactly the same as the one of <code class="classname">boost::lock_guard</code>.</p>
<p>If a value of type <code class="type">boost::try_to_lock</code> is passed as the second parameter, the corresponding constructor calls <code class="methodname">try_lock()</code> instead. This method returns a value of type <code class="type">bool</code>: <code class="literal">true</code> if the mutex could be acquired, <code class="literal">false</code> if not. Opposed to the <code class="methodname">lock()</code> method, <code class="methodname">try_lock()</code> returns immediately and does not block until the mutex has been acquired.</p>
<p>The above program passes <var>boost::try_to_lock</var> as the second parameter to the constructor of <code class="classname">boost::unique_lock</code>. Whether or not the mutex has been acquired can be checked via the <code class="methodname">owns_lock()</code> method afterwards. In case it has not - <code class="methodname">owns_lock()</code> returns <code class="literal">false</code> - another function provided by <code class="classname">boost::unique_lock</code> is used: <code class="methodname">timed_lock()</code> waits for a certain time to acquire the mutex. The given program waits for up to one second which should be more than enough time to acquire the mutex.</p>
<p>The example actually shows the three fundamental ways of acquiring a mutex: <code class="methodname">lock()</code> waits until the mutex has been acquired. <code class="methodname">try_lock()</code> does not wait but acquires the mutex if it is available at the time of the call and returns <code class="literal">false</code> otherwise. Finally, <code class="methodname">timed_lock()</code> tries to acquire the mutex within a given period of time. As with <code class="methodname">try_lock()</code>, success or failure is indicated by the return value of type <code class="type">bool</code>.</p>
<p>While both <code class="methodname">lock()</code> and <code class="methodname">try_lock()</code> are provided by <code class="classname">boost::mutex</code>, <code class="methodname">timed_lock()</code> is only supported by <code class="classname">boost::timed_mutex</code> instead which is the reason for its usage in the above example program. Without using <code class="methodname">timed_lock()</code>, the mutex can be of type <code class="classname">boost::mutex</code> as seen in the previous example.</p>
<p>Just like <code class="classname">boost::lock_guard</code>, the destructor of <code class="classname">boost::unique_lock</code> releases the mutex accordingly. In addition, the mutex can be manually released using the <code class="methodname">unlock()</code> method. It is also possible to remove the association between the <code class="classname">boost::unique_lock</code> class and the mutex by calling <code class="methodname">release()</code> as done in the above example. In this case however, the mutex must be released using the <code class="methodname">unlock()</code> method explicitly as it is not done automatically by the destructor of <code class="classname">boost::unique_lock</code> anymore.</p>
<p><code class="classname">boost::unique_lock</code> is a so-called exclusive lock meaning that only one thread at a time can acquire the mutex. Other threads are required to wait until the mutex has been released again. Besides exclusive locks there are also non-exclusive ones. Boost.Thread provides a class named <code class="classname">boost::shared_lock</code> to support non-exclusive locks accordingly. This class must be used together with a mutex of type <code class="classname">boost::shared_mutex</code> as shown in the following example.</p>
<pre class="programlisting">#include &lt;boost/thread.hpp&gt; 
#include &lt;iostream&gt; 
#include &lt;vector&gt; 
#include &lt;cstdlib&gt; 
#include &lt;ctime&gt; 

void wait(int seconds) 
{ 
  boost::this_thread::sleep(boost::posix_time::seconds(seconds)); 
} 

boost::shared_mutex mutex; 
std::vector&lt;int&gt; random_numbers; 

void fill() 
{ 
  std::srand(static_cast&lt;unsigned int&gt;(std::time(0))); 
  for (int i = 0; i &lt; 3; ++i) 
  { 
    boost::unique_lock&lt;boost::shared_mutex&gt; lock(mutex); 
    random_numbers.push_back(std::rand()); 
    lock.unlock(); 
    wait(1); 
  } 
} 

void print() 
{ 
  for (int i = 0; i &lt; 3; ++i) 
  { 
    wait(1); 
    boost::shared_lock&lt;boost::shared_mutex&gt; lock(mutex); 
    std::cout &lt;&lt; random_numbers.back() &lt;&lt; std::endl; 
  } 
} 

int sum = 0; 

void count() 
{ 
  for (int i = 0; i &lt; 3; ++i) 
  { 
    wait(1); 
    boost::shared_lock&lt;boost::shared_mutex&gt; lock(mutex); 
    sum += random_numbers.back(); 
  } 
} 

int main() 
{ 
  boost::thread t1(fill); 
  boost::thread t2(print); 
  boost::thread t3(count); 
  t1.join(); 
  t2.join(); 
  t3.join(); 
  std::cout &lt;&lt; "Summe: " &lt;&lt; sum &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/6.3.4/main.cpp">Download source code</a></li></ul>
<p>Non-exclusive locks of type <code class="classname">boost::shared_lock</code> can be used if threads only need read-only access to a specific resource. A thread modifying the resource needs write access and thus requires an exclusive lock. The reason for that should be obvious: Threads with read-only access do not recognize other threads accessing the same resource at the same time. Non-exclusive locks can therefore share a mutex.</p>
<p>In the given example, both <code class="function">print()</code> and <code class="function">count()</code> access <var>random_numbers</var> read-only. While the <code class="function">print()</code> function writes the last number of <var>random_numbers</var> to the standard output stream, the <code class="function">count()</code> function adds it to the variable <var>sum</var>. Since neither function modifies <var>random_numbers</var>, both can access it at the same time using a non-exclusive lock of type <code class="classname">boost::shared_lock</code>.</p>
<p>Inside the <code class="function">fill()</code> function, an exclusive lock of type <code class="classname">boost::unique_lock</code> is required since it inserts new random numbers into <var>random_numbers</var>. The mutex is explicitly released using the <code class="methodname">unlock()</code> method before <code class="function">fill()</code> waits for one second. Opposed to the previous example, <code class="function">wait()</code> is called at the end of the <code class="code">for</code> loop to guarantee that at least one random number exists in the container before it is accessed by either <code class="function">print()</code> or <code class="function">count()</code>. Both of these functions call the <code class="function">wait()</code> function at the beginning of their <code class="code">for</code> loop accordingly.</p>
<p>Looking at the individual calls to the <code class="function">wait()</code> function from different locations, one potential issue becomes apparent: The order of the function calls is directly affected by the order in which the CPU actually executes the individual threads. Using so-called condition variables, the individual threads can be synchronized so that elements added to <var>random_numbers</var> are immediately processed by a different thread accordingly.</p>
<pre class="programlisting">#include &lt;boost/thread.hpp&gt; 
#include &lt;iostream&gt; 
#include &lt;vector&gt; 
#include &lt;cstdlib&gt; 
#include &lt;ctime&gt; 

boost::mutex mutex; 
boost::condition_variable_any cond; 
std::vector&lt;int&gt; random_numbers; 

void fill() 
{ 
  std::srand(static_cast&lt;unsigned int&gt;(std::time(0))); 
  for (int i = 0; i &lt; 3; ++i) 
  { 
    boost::unique_lock&lt;boost::mutex&gt; lock(mutex); 
    random_numbers.push_back(std::rand()); 
    cond.notify_all(); 
    cond.wait(mutex); 
  } 
} 

void print() 
{ 
  std::size_t next_size = 1; 
  for (int i = 0; i &lt; 3; ++i) 
  { 
    boost::unique_lock&lt;boost::mutex&gt; lock(mutex); 
    while (random_numbers.size() != next_size) 
      cond.wait(mutex); 
    std::cout &lt;&lt; random_numbers.back() &lt;&lt; std::endl; 
    ++next_size; 
    cond.notify_all(); 
  } 
} 

int main() 
{ 
  boost::thread t1(fill); 
  boost::thread t2(print); 
  t1.join(); 
  t2.join(); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/6.3.5/main.cpp">Download source code</a></li></ul>
<p>The program in this example removed the <code class="function">wait()</code> and <code class="function">count()</code> functions. Threads do no longer wait for one second with every loop iteration but rather execute as fast as possible. Additionally, no total is calculated; numbers are solely written to the standard output stream.</p>
<p>To ensure correct processing of the random numbers, the individual threads are synchronized by a conditional variable that allows to check for certain conditions between multiple threads.</p>
<p>As before, the <code class="function">fill()</code> function generates a random number with each iteration and places it in the <var>random_numbers</var> container. To block other threads from accessing the container at the same time, an exclusive lock is taken accordingly. Instead of waiting for one second, this example actually uses a conditional variable instead. Calling the <code class="methodname">notify_all()</code> method will wake up every thread that has been waiting for this notification by calling the <code class="methodname">wait()</code> method, respectively.</p>
<p>By looking at the <code class="code">for</code> loop of the <code class="function">print()</code> function, one can see that for the same conditional variable a method named <code class="methodname">wait()</code> is called. If the thread is woken up by a call to <code class="function">notify_all()</code>, it tries to acquire the mutex which will only succeed after it has been successfully released in the <code class="function">fill()</code> function.</p>
<p>The trick here is that calling <code class="methodname">wait()</code> also releases the corresponding mutex passed as parameter. After calling <code class="methodname">notify_all()</code>, the <code class="function">fill()</code> function releases the mutex by calling <code class="methodname">wait()</code> accordingly. It then blocks and waits for some other thread to call <code class="methodname">notify_all()</code> which happens in the <code class="function">print()</code> function once the random number has been written to the standard output stream.</p>
<p>Notice that the call to the <code class="methodname">wait()</code> method inside the <code class="function">print()</code> function actually happens within a separate <code class="code">while</code> loop. This is done to handle the scenario where a random number has already been placed in the container before the <code class="methodname">wait()</code> method is called for the first time in <code class="function">print()</code>. By comparing the number of stored elements in <var>random_numbers</var> with the expected number of elements, this scenario is successfully handled and the random number is written to the standard output stream.</p>
</div>
<hr>
<h2 class="title">
<a name="multithreading_thread_local_storage"></a>6.4 Thread Local Storage</h2>
<div class="sect1">
<p>Thread Local Storage (TLS) is a dedicated storage area that can only be accessed by one thread. TLS variables can be seen as global variables only visible to a particular thread instead of the whole program. The following example shows the benefits of these variables.</p>
<pre class="programlisting">#include &lt;boost/thread.hpp&gt; 
#include &lt;iostream&gt; 
#include &lt;cstdlib&gt; 
#include &lt;ctime&gt; 

void init_number_generator() 
{ 
  static bool done = false; 
  if (!done) 
  { 
    done = true; 
    std::srand(static_cast&lt;unsigned int&gt;(std::time(0))); 
  } 
} 

boost::mutex mutex; 

void random_number_generator() 
{ 
  init_number_generator(); 
  int i = std::rand(); 
  boost::lock_guard&lt;boost::mutex&gt; lock(mutex); 
  std::cout &lt;&lt; i &lt;&lt; std::endl; 
} 

int main() 
{ 
  boost::thread t[3]; 

  for (int i = 0; i &lt; 3; ++i) 
    t[i] = boost::thread(random_number_generator); 

  for (int i = 0; i &lt; 3; ++i) 
    t[i].join(); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/6.4.1/main.cpp">Download source code</a></li></ul>
<p>The example creates three threads, each writing a random number to the standard output stream. The <code class="function">random_number_generator()</code> function utilizes the <code class="function">std::rand()</code> function, defined in the C++ standard, to create the random numbers. However, the generator used for <code class="function">std::rand()</code> must be properly initialized with the <code class="function">std::srand()</code> function. If not, the program will always print the same random number.</p>
<p>Initializing the random number generator takes place inside the <code class="function">init_number_generator()</code> function with the aid of the <code class="function">std::time()</code> function returning the current time. Since this value differs every time the application is executed, it is guaranteed that the generator is always initialized with a different value and thus provides new random numbers. Since the generator only needs to be initialized once, <code class="function">init_number_generator()</code> uses a static variable named <var>done</var> as the condition.</p>
<p>If the program is executed a couple of times, it becomes apparent that two of the three random numbers written are always the same. The program actually has a defect: The generator on which <code class="function">std::rand()</code> is based must be initialized for every thread using the function. Therefore, the implementation of <code class="function">init_number_generator()</code> is actually incorrect since it only calls <code class="function">std::srand()</code> once. Using TLS, this defect can be rectified.</p>
<pre class="programlisting">#include &lt;boost/thread.hpp&gt; 
#include &lt;iostream&gt; 
#include &lt;cstdlib&gt; 
#include &lt;ctime&gt; 

void init_number_generator() 
{ 
  static boost::thread_specific_ptr&lt;bool&gt; tls; 
  if (!tls.get()) 
    tls.reset(new bool(false)); 
  if (!*tls) 
  { 
    *tls = true; 
    std::srand(static_cast&lt;unsigned int&gt;(std::time(0))); 
  } 
} 

boost::mutex mutex; 

void random_number_generator() 
{ 
  init_number_generator(); 
  int i = std::rand(); 
  boost::lock_guard&lt;boost::mutex&gt; lock(mutex); 
  std::cout &lt;&lt; i &lt;&lt; std::endl; 
} 

int main() 
{ 
  boost::thread t[3]; 

  for (int i = 0; i &lt; 3; ++i) 
    t[i] = boost::thread(random_number_generator); 

  for (int i = 0; i &lt; 3; ++i) 
    t[i].join(); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/6.4.2/main.cpp">Download source code</a></li></ul>
<p>The static variable <var>done</var> has been replaced with a TLS variable <var>tls</var> which is based on the template class <code class="classname">boost::thread_specific_ptr</code> - instantiated with the data type <code class="type">bool</code>. In principle, <var>tls</var> works just like <var>done</var>: It acts as a condition indicating whether or not the random number generator has already been initialized. The crucial difference, however, is that the value stored by <var>tls</var> is only visible and available to the corresponding thread.</p>
<p>Once a variable of type <code class="classname">boost::thread_specific_ptr</code> is created, it can be set accordingly. However, it now expects the address of a variable of type <code class="type">bool</code> instead of the variable itself. Using the <code class="methodname">reset()</code> method, the corresponding address can be stored in <var>tls</var>. In the given example, a variable of type <code class="type">bool</code> is dynamically allocated and its address, returned by <code class="code">new</code>, is stored in <var>tls</var>. To avoid setting <var>tls</var> every time the <code class="function">init_number_generator()</code> function is called, it first checks whether an address is already stored via the <code class="methodname">get()</code> method.</p>
<p>Since <code class="classname">boost::thread_specific_ptr</code> stores an address, it behaves like a regular pointer. Consequently, both the <code class="methodname">operator*()</code> and <code class="methodname">operator-&gt;()</code> operators are overloaded to simplify the usage. The example uses <code class="code">*tls</code> to check whether the condition is currently <code class="literal">true</code> or <code class="literal">false</code>. Depending on the current condition, the random number generator is either initialized or not.</p>
<p>As seen, <code class="classname">boost::thread_specific_ptr</code> allows storing the address of an object for the current thread and only allows the current thread to retrieve the same address later on. While one thread already stored the address successfully, a different thread may have not.</p>
<p>If the program is now executed, it may come as a surprise that despite the TLS variable, the random numbers generated are still equal. This is due to the fact that all three threads are created at the same time and thus, the random number generators are initialized with the same time as well. If the program is executed a couple of times however, the random numbers will change indicating that the generators itself are initialized correctly.</p>
</div>
<hr>
<h2 class="title">
<a name="multithreading_exercises"></a>6.5 Exercises</h2>
<div class="sect1">
<p class="solution">
              You can buy 
              <a target="_top" href="http://en.highscore.de/shop/index.php?p=boost-solution">solutions to all exercises</a>
              in this book as a ZIP file. 
            </p>
<ol>
<li class="listitem">
<p>Refactor the following program to calculate the total using two threads. Since many processors nowadays have two cores, the execution time should decrease by utilizing threads.</p>
<pre class="programlisting">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; 
#include &lt;boost/cstdint.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time(); 

  boost::uint64_t sum = 0; 
  for (int i = 0; i &lt; 1000000000; ++i) 
    sum += i; 

  boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time(); 
  std::cout &lt;&lt; end - start &lt;&lt; std::endl; 

  std::cout &lt;&lt; sum &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/6.5.1/main.cpp">Download source code</a></li></ul>
</li>
<li class="listitem"><p>Generalize the program from exercise 1 by utilizing as many threads as the processor can physically execute at the same time. For example, if the processor contains four cores, a total of four threads should be utilized.</p></li>
<li class="listitem">
<p>Change the following program by executing the <code class="function">thread()</code> function in its own thread created in <code class="function">main()</code>. The program should calculate the total and write it to the standard output stream twice. The implementation of <code class="function">calculate()</code>, <code class="function">print()</code> and <code class="function">thread()</code> can be modified however, the signature of each function needs to stay the same. In other words, each function should still neither require any parameters nor return a value.</p>
<pre class="programlisting">#include &lt;iostream&gt; 

int sum = 0; 

void calculate() 
{ 
  for (int i = 0; i &lt; 1000; ++i) 
    sum += i; 
} 

void print() 
{ 
  std::cout &lt;&lt; sum &lt;&lt; std::endl; 
} 

void thread() 
{ 
  calculate(); 
  print(); 
} 

int main() 
{ 
  thread(); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/6.5.2/main.cpp">Download source code</a></li></ul>
</li>
</ol>
</div>
</div>
<hr class="hrfoot">
<p class="copyright">Copyright © 2008-2010 
        <a class="link" href="mailto:boris@highscore.de">Boris Schäling</a>
      </p>
</body>
</html>
